home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1999 / MacHack 1999.toast / The Hacks / AltiVec Effect / EffectUtilities.c < prev    next >
Encoding:
C/C++ Source or Header  |  1998-03-13  |  6.6 KB  |  225 lines  |  [TEXT/CWIE]

  1. /*
  2.     File:        EffectUtilities.c
  3.  
  4.     Contains:    Tween utilities to help you write effect components
  5.  
  6.     Written by:    Tom Dowdy
  7.  
  8.     Copyright:    © 1997-1998 by Apple Computer, Inc., all rights reserved.
  9.     
  10. */
  11.  
  12. #include <ImageCodec.h>
  13. #include <NumberFormatting.h>
  14. #include "EffectUtilities.h"
  15. #include "BltMacros.h"
  16.  
  17. // ----------------------------------------------------------------------------------------
  18. int LocalMemCmp(Ptr a, Ptr b, Size length)
  19. {
  20.     while (length--)
  21.         {
  22.         if (*a++ != *b++)
  23.             return(1);
  24.         }
  25.         
  26.     return(0);
  27.  
  28. } // LocalMemCmp
  29.  
  30. // ----------------------------------------------------------------------------------------
  31. OSErr CreateTweenRecord(
  32.             TweenGlobals *glob,             // input: our globals
  33.             TweenContainerRecord *pTween,     // input/output: tween record to initialize
  34.             OSType paramterType,            // input: where to find parameter (type)
  35.             long parameterID,                // input: where to find parameter (ID)
  36.             Size parameterSize,             // input: size of parameters
  37.             OSType dataType,                // input: type of tween, 0 for none
  38.             void *startValue,                // input: pointer or start value of default (for long size, just the data)
  39.             void *endValue,                    // input: pointer or end value of default (for long size, just the data)
  40.             TimeValue duration)                // input: duration of the tween
  41. {
  42.     OSErr    anErr = noErr;
  43.  
  44.     // all done?
  45.     if (pTween->readyToGo)
  46.         return(noErr);
  47.         
  48.     /* If we don't have the data handle, make one */
  49.     if (pTween->tweenData == nil)
  50.         {
  51.         pTween->tweenData = NewHandleClear(parameterSize);
  52.         anErr = MemError();
  53.         if (anErr == noErr)
  54.             {
  55.             if (parameterSize == sizeof(unsigned long))
  56.                 ((unsigned long*)(*(pTween->tweenData)))[0] = (unsigned long) EndianU32_NtoB(startValue);
  57.             else
  58.                 BlockMoveData((Ptr) startValue, *(pTween->tweenData), parameterSize);
  59.             }
  60.         }
  61.         
  62.     /* If we don't have the tweeners set up yet, do so here */
  63.     if ( (anErr == noErr) && (pTween->tween == nil) )
  64.         {
  65.         QTAtom    atom;
  66.         
  67.         // find the parameter atom, if it exists
  68.         atom = QTFindChildByID ( glob->parameters, kParentAtomIsContainer,
  69.                                 paramterType, parameterID, nil);
  70.         if ( (atom) && (QTCountChildrenOfType(glob->parameters, atom, kTweenData) > 0) )
  71.             {
  72.             anErr = QTNewTween(&pTween->tween, glob->parameters, atom, duration);
  73.             glob->atLeastOneTweener = true;
  74.             }
  75.         else
  76.             {
  77.             // okay, we either have a constant value, or need to default
  78.             if (atom)
  79.                 {
  80.                 anErr = QTCopyAtomDataToHandle(glob->parameters, atom, pTween->tweenData);
  81.                 #if TARGET_RT_LITTLE_ENDIAN
  82.                 switch (dataType)
  83.                 {
  84.                     case kParameterTypeDataLong:
  85.                     case kParameterTypeDataFixed:
  86.                         **(long**)(pTween->tweenData) = EndianS32_BtoN(**(long**)(pTween->tweenData));
  87.                         break;
  88.                     case kParameterTypeDataRGBValue:
  89.                         MyEndianRGBColor(**(RGBColor**)pTween->tweenData);
  90.                         break;
  91.                     case kParameterTypeDataDouble:
  92.                         MyEndianQTFloatDouble(**pTween->tweenData);
  93.                         break;
  94.                 }
  95.                 #endif
  96.                 }
  97.             else
  98.                 {
  99.                 if (dataType != 0)
  100.                     {
  101.                     QTAtom    tweenAtom;
  102.                     Boolean    valuesAreSame = false;
  103.                     
  104.                     if (glob->defaultParameters == nil)
  105.                         anErr = QTNewAtomContainer(&glob->defaultParameters);
  106.                     
  107.                     anErr = QTInsertChild(glob->defaultParameters, kParentAtomIsContainer, kTweenEntry, 0, 0,
  108.                                                     0, nil, &tweenAtom);
  109.  
  110.                     if (anErr == noErr) 
  111.                     {
  112.                         dataType = EndianU32_NtoB(dataType);
  113.                         QTInsertChild(glob->defaultParameters, tweenAtom, kTweenType, 0, 0,
  114.                                                     sizeof(dataType), &dataType, nil);
  115.                     }
  116.                     
  117.                     if (anErr == noErr)
  118.                         {
  119.                         SetHandleSize(pTween->tweenData, parameterSize * 2);
  120.                         anErr = MemError();
  121.                         }
  122.  
  123.                     if (anErr == noErr)
  124.                         {
  125.                         HLock(pTween->tweenData);
  126.                         if (parameterSize == sizeof(unsigned long))
  127.                             {
  128.                             ((unsigned long*)(*(pTween->tweenData)))[0] = (unsigned long) EndianU32_NtoB(startValue);
  129.                             ((unsigned long*)(*(pTween->tweenData)))[1] = (unsigned long) EndianU32_NtoB(endValue);
  130.                             
  131.                             if (startValue == endValue)
  132.                                 valuesAreSame = true;
  133.                             }
  134.                         else
  135.                             {
  136.                             BlockMoveData((Ptr) startValue, *(pTween->tweenData), parameterSize);
  137.                             BlockMoveData((Ptr) endValue, (*(pTween->tweenData))+parameterSize, parameterSize);
  138.                             
  139.                             if (LocalMemCmp(startValue, endValue, parameterSize) == 0)
  140.                                 valuesAreSame = true;
  141.                             }
  142.                         anErr = QTInsertChild(glob->defaultParameters, tweenAtom, kTweenData, 1, 0,
  143.                                                 parameterSize*2, *(pTween->tweenData), nil);
  144.                         HUnlock(pTween->tweenData);
  145.                         SetHandleSize(pTween->tweenData, parameterSize);
  146.                         }
  147.                     if ( anErr == noErr )
  148.                         {
  149.                         if (valuesAreSame)
  150.                             {
  151.                             // flip back to native format, so effect can just read from it
  152.                             ((unsigned long*)(*(pTween->tweenData)))[0] = (unsigned long) startValue;
  153.                             }
  154.                         else
  155.                             {
  156.                             anErr = QTNewTween(&pTween->tween, glob->defaultParameters, tweenAtom, duration);
  157.                             glob->atLeastOneTweener = true;
  158.                             }
  159.                         }
  160.                     } // we need to create a default tween
  161.                 else
  162.                     {
  163.                     // note that we store in native format, so that effect can just read from it
  164.                     if (parameterSize == sizeof(unsigned long))
  165.                         ((unsigned long*)(*(pTween->tweenData)))[0] = (unsigned long) startValue;
  166.                     else
  167.                         BlockMoveData((Ptr) startValue, *(pTween->tweenData), parameterSize);
  168.                     } // we don't have a tween, just a default single value
  169.                     
  170.                 } // if we default the value
  171.             
  172.             } // if we don't have existing tween
  173.             
  174.         } // need to make the tween
  175.             
  176.     if (anErr == noErr)
  177.         pTween->readyToGo = true;
  178.         
  179.     return(anErr);
  180.     
  181. } // CreateTweenRecord
  182.  
  183. // ----------------------------------------------------------------------------------------
  184. void DisposeTweenRecord(TweenContainerRecord *pTween)
  185. {
  186.     if (pTween->tween)
  187.         {
  188.         QTDisposeTween(pTween->tween);
  189.         pTween->tween = nil;
  190.         }
  191.     if (pTween->tweenData)
  192.         {
  193.         DisposeHandle(pTween->tweenData);
  194.         pTween->tweenData = nil;
  195.         }
  196.  
  197.     pTween->readyToGo = false;
  198.     
  199. } // DisposeTweenRecord
  200.  
  201. // ----------------------------------------------------------------------------------------
  202. OSErr InitializeTweenGlobals(TweenGlobals *pTweenGlobals, CodecDecompressParams *p)
  203. {
  204.     return PtrToHand(p->data, (Handle*)&(pTweenGlobals->parameters), p->bufferSize);
  205.     
  206. } // InitializeTweenGlobals
  207.  
  208. // ----------------------------------------------------------------------------------------
  209. void DisposeTweenGlobals(TweenGlobals *pTweenGlobals)
  210. {
  211.     if (pTweenGlobals->defaultParameters)
  212.         {
  213.         QTDisposeAtomContainer(pTweenGlobals->defaultParameters);
  214.         pTweenGlobals->defaultParameters = nil;
  215.         }
  216.     pTweenGlobals->atLeastOneTweener = false;
  217.     if (pTweenGlobals->parameters)
  218.         {
  219.         DisposeHandle((Handle)pTweenGlobals->parameters);
  220.         pTweenGlobals->parameters = nil;
  221.         }
  222.     
  223. } // DisposeTweenGlobals
  224.  
  225.